home *** CD-ROM | disk | FTP | other *** search
- /*
- * peak.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /* PEAK: program finds a peak in a given area using the
- * converging squares algorithm, a multi-resolution approach.
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <tiffimage.h> /* tiff info on images */
- #include <images.h>
- extern void print_sos_lic ();
-
- #define SIZE_FINAL_DFLT 5 /* final size of converging squares */
- #define INBOUNDX(X) ((X) >= 0 && (X) < imgSize.x)
- #define INBOUNDY(Y) ((Y) >= 0 && (Y) < imgSize.y)
-
- int usage (short);
- int input (int, char **, long *, long *, long *, long *, short *);
- long convsqrs (unsigned char *, long, long, int, int, int, int,
- int *, int *);
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- Image *imgI; /* I/O image structure */
- unsigned char **image; /* input/output image */
- unsigned char *pImage; /* pointer to image array */
- long x0, y0; /* initial top-left region coord.s */
- long size0, sizeF; /* initial/final region size for peak detection */
- short dFlag; /* if =1, displays path of conv. sqrs to peak */
- struct point imgSize; /* image dimensions */
- long rowPeak, colPeak; /* location of peak */
- long x, y, i, j;
-
- /* read user parameter values */
- if ((input (argc, argv, &x0, &y0, &size0, &sizeF, &dFlag)) < 0)
- return (-1);
-
- /* open image */
- imgI = ImageIn (argv[1]);
- image = imgI->img;
- imgSize.y = ImageGetHeight (imgI);
- imgSize.x = ImageGetWidth (imgI);
- printf ("image size is %dx%d\n", imgSize.x, imgSize.y);
-
- pImage = (unsigned char *) calloc (imgSize.x * imgSize.y,
- sizeof (unsigned char));
- for (y = 0, i = 0; y < imgSize.y; y++)
- for (x = 0; x < imgSize.x; x++)
- pImage[i++] = image[y][x];
-
- /* find peaks */
- if (size0 == -1)
- size0 = (imgSize.x < imgSize.y) ? imgSize.x : imgSize.y;
- convsqrs (pImage, imgSize.x, imgSize.y, y0, x0, size0, sizeF,
- (int *) &rowPeak, (int *) &colPeak);
- printf ("rowPeak = %d, colPeak = %d\n", rowPeak, colPeak);
-
- /* display peak */
- if (dFlag) { /* display peak if flag set */
- for (i = rowPeak - 3; i <= rowPeak + 3; i++) {
- if (INBOUNDY (i)) {
- if (INBOUNDX (colPeak - 3))
- image[i][colPeak - 3] = (image[i][colPeak - 3] > 128) ? 0 : 255;
- if (INBOUNDX (colPeak + 4))
- image[i][colPeak + 3] = (image[i][colPeak + 3] > 128) ? 0 : 255;
- }
- }
- for (j = colPeak - 2; j <= colPeak + 2; j++) {
- if (INBOUNDX (j)) {
- if (INBOUNDY (rowPeak - 3))
- image[rowPeak - 3][j] = (image[rowPeak - 3][j] > 128) ? 0 : 255;
- if (INBOUNDY (rowPeak + 4))
- image[rowPeak + 3][j] = (image[rowPeak + 3][j] > 128) ? 0 : 255;
- }
- }
- }
-
- ImageOut (argv[2], imgI);
- return (0);
- }
-
- /* USAGE: function gives instructions on usage of program
- * usage: usage (flag)
- * When flag is 1, the long message is given, 0 gives short.
- */
-
- int
- usage (flag)
- short flag; /* flag =1 for long message; =0 for short message */
- {
-
- /* print short usage message or long */
- printf ("USAGE: peak inimg outimg -x X0 -y Y0 -s SIZE_INITIAL\n");
- printf (" [-f SIZE_FINAL] [-d] [-L]\n");
- if (flag == 0)
- return (-1);
-
- printf ("\npeak finds peak in given region of an image.\n");
- printf ("NOTE: this program finds ONE peak based on iteratively\n");
- printf (" reducing the region size; therefore the initially chosen\n");
- printf (" region location and size strongly affects which peak will be chosen.\n");
- printf (" this program works best for convex shapes with smoothly\n");
- printf (" changing slopes; it may give strange results for geometric shapes,\n");
- printf (" especially those with edges aligned to horizontal or vertical axes.\n\n");
- printf ("ARGUMENTS:\n");
- printf (" inimg: input image filename (TIF)\n");
- printf (" outimg: output image filename (TIF)\n");
- printf (" -x X0: top left x-coord of region\n");
- printf (" -y Y0: top left y-coord of region\n");
- printf (" -s SIZE_INITIAL: square size of region in which to find peak\n");
- printf (" NOTE: -x, -y and -s values must\n");
- printf (" be set by the user\n\n");
- printf ("OPTIONS:\n");
- printf (" -f SIZE_FINAL: final square size, after which peak pixel\n");
- printf (" -d: to display peak location.\n");
- printf (" -L: print Software License for this module\n");
-
- return (-1);
- }
-
-
- /* INPUT: function reads input parameters
- * usage: input (argc, argv, &x0, &y0, &size0, &sizeF, &dFlag)
- */
-
- #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
-
- int
- input (argc, argv, x0, y0, size0, sizeF, dFlag)
- int argc;
- char *argv[];
- long *x0, *y0; /* initial top-left region coord.s */
- long *size0, *sizeF; /* initial/final region size for peak detection */
- short *dFlag; /* if =1, displays path of conv. sqrs. */
- {
- long n;
-
- if (argc == 1)
- USAGE_EXIT (1);
- if (argc == 2)
- USAGE_EXIT (0);
-
- *x0 = *y0 = -1;
- *size0 = -1;
- *sizeF = SIZE_FINAL_DFLT;
- *dFlag = 0;
-
- for (n = 3; n < argc; n++) {
- if (strcmp (argv[n], "-x") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *x0 = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-y") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *y0 = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-s") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *size0 = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-f") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (0);
- *sizeF = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-d") == 0)
- *dFlag = 1;
- else if (strcmp (argv[n], "-L") == 0) {
- print_sos_lic ();
- exit (0);
- }
- else
- USAGE_EXIT (0);
- }
-
- if (*x0 == -1 || *y0 == -1 || *size0 == -1)
- USAGE_EXIT (1);
-
- return (0);
- }
-